/**
 * @desc
 * 模板处理工具类
 * 1.
 *
 * @使用场景
 *
 * @author  杨晓东[of1081]
 * @company qianmi.com
 * @Date    16/4/18
 **/
'use strict';

let templateUtil = module.exports={};

let Immutable  =require('immutable');
let fse = require('fs-extra');
let path  =require('path');
let _util = require('./_util');

let widetUtil =require('@qianmi/x-site-common/util/widget-util');
let desiginerN = _util.getWorbenchName();

/**
 * 根据模板配置文件,生成模板加载JS文件...
 * 包含组件集合, 插件
 * @param templateConfigPath    模板配置文件路径;
 */
templateUtil.generateTplInfo = function * (templateConfigPath){
    //读取模板配置文件内容::
    let templateConfig =  yield _readTempConfig(templateConfigPath);
    templateConfig =_dealTemplateConfig({templateConfig,templateConfigPath});
    let dependenciesBar  =analyseTemplateDependentBar({templateConfig});
    templateConfig.dependenciesBar = dependenciesBar;
    return templateConfig;
}

function * _readTempConfig(templateConfigPath) {
    return new Promise((resolve)=>{
        fse.readJson(templateConfigPath, function (err, templateConfig) {
            if(err){
                throw err;
            }else {
                resolve(templateConfig);
            }
        });
    });
}
/**
 * 获取模板配置信息
 * 处理数据重定义,等一些设置的问题..
 *
 * @param templateConfigPath
 */
function  _dealTemplateConfig({templateConfig,templateConfigPath}){
    // return new Promise((resolve)=>{
        
        if(templateConfig.barDefaultPropsMap){//组件条的属性跟着模板走..的转换.
            for(let _widgetNameSpace in templateConfig.barDefaultPropsMap){
                let _widgetBarPropFile =path.join(templateConfigPath,'..',templateConfig.barDefaultPropsMap[_widgetNameSpace]);

                if(_widgetBarPropFile.endsWith('.json')){ //  TODO 其实只要JS类型的就可以了,JSON这种类型的包含在其中
                    templateConfig.barDefaultPropsMap[_widgetNameSpace]=fse.readJsonSync(_widgetBarPropFile);
                }else if(_widgetBarPropFile.endsWith('.js')){
                    templateConfig.barDefaultPropsMap[_widgetNameSpace]=require(_widgetBarPropFile);
                } else {
                    throw new Error('默认数据配置不正确!!~'+file);
                }
            }
        }

        //children如果是级呢? 这里不需要这个了.
        templateConfig.children=templateConfig.children.map(function(childrenItem){
            if(!childrenItem.widgetNameSpace){
                throw new Error(templateConfigPath+'模板children中widgetNameSpace未定义完整'+JSON.stringify(childrenItem));
            }
            //childrenItem.widgetNameSpace=path.join(dirPath,childrenItem.widgetFile).replace(/\\/g,'/');

            if(childrenItem.initPropsFile){
                console.log('把initPropsFile汇总到templateConfig');
                let childrenItemInitProsp = path.join(templateConfigPath,'..',childrenItem.initPropsFile);
                //FileNameSpace=path.join(dirPath,childrenItem.widgetFile).replace(/\\/g,'/');
                if(childrenItem.initPropsFile.endsWith(".json")){
                    childrenItem.initProps = require("../"+childrenItemInitProsp);
                } else if(childrenItemInitProsp.endsWith('.js')){
                    childrenItem.initProps = require("../"+childrenItemInitProsp);
                }
            }

            childrenItem.widget=widetUtil.extraWidgetNameFromPath(childrenItem.widgetNameSpace);
            return childrenItem;
        });

        if(templateConfig.nsTransferMap){
            console.log('对nsTransferMap进行处理,自动详细记录组件信息');
            for(let platForm  in templateConfig.nsTransferMap){
                let widgetNameMap = {};
                if( templateConfig.nsTransferMap[platForm].barMap){


                    for(let ns in  templateConfig.nsTransferMap[platForm].barMap){
                        let  toNs =templateConfig.nsTransferMap[platForm].barMap[ns];
                        widgetNameMap[widetUtil.extraWidgetNameFromPath(ns)] =widetUtil.extraWidgetNameFromPath(toNs);
                    }
                }

                if( templateConfig.nsTransferMap[platForm].groupMap){
                    for(let ns in  templateConfig.nsTransferMap[platForm].groupMap) {
                        let toNs = templateConfig.nsTransferMap[platForm].groupMap[ns];

                        widgetNameMap[widetUtil.extraWidgetNameFromPath(ns)] =widetUtil.extraWidgetNameFromPath(toNs);
                    }
                }

                templateConfig.nsTransferMap[platForm].widgetNameMap = widgetNameMap;
            }

        }
        return templateConfig;
}



/**
 * 分析出模板所依赖的所有组件
 * @param templateCnnfig
 */
function analyseTemplateDependentBar({templateConfig}){
    let result =[];
    //console.log('template::',templateConfig.templateName);
    templateConfig.children.forEach(childitem=>{
        //根据一个名命空间, 找出其子元素所有的名命空间
        result.push(childitem.widgetNameSpace);
        result = result.concat(searchNameSpaceFromFile(childitem.widgetNameSpace).toJS());
    });

    templateConfig.acceptBars && templateConfig.acceptBars.forEach(barItem=>{
        result.push(barItem);
        result = result.concat(searchNameSpaceFromFile(barItem).toJS());
    });

    templateConfig.pluginBars && templateConfig.pluginBars.forEach(barItem=>{
        result.push(barItem);
        result = result.concat(searchNameSpaceFromFile(barItem).toJS());
    });

    templateConfig.adapterBars && templateConfig.adapterBars.forEach(barItem=>{
        result.push(barItem);
        result = result.concat(searchNameSpaceFromFile(barItem).toJS());
    });

    return result;
}

/**
 * 根据指定组件 找到其直接或间接依赖的子组件
 * @param widgetNameSpace 组件命名空间
 * @param topDir 顶部目录
 **/
function searchNameSpaceFromFile(widgetNameSpace){
    let widgetWorkBench = widgetNameSpace.split('/');
    let barIndex;
    if( widgetWorkBench[0] === desiginerN){
        barIndex  = fse.readJsonSync(path.join(__dirname,'../dist/barIndex.json'));
        return Immutable.fromJS(barIndex[widgetNameSpace].dependenciesBar || []);
    } else {
         barIndex  = fse.readJsonSync(path.join(__dirname,'@qianmi/'+widgetWorkBench[0],'dist/barIndex.json'));
    }
    return Immutable.fromJS(barIndex[widgetNameSpace].dependenciesBar || []);
}



/**
 * 把对bar的依赖转化为文本内容
 * @param widgetArray 模板直接或间接依赖的组件条与组件块
 * @param templateConfig  模板配置, 主要使用其数据适配内容
 */
function  transferBar2Content(widgetArray,templateConfig){

    var pathList =[];
    //pathList.push('var widgetRep={},widgetProxyRep={};');

    pathList.push("'use strict'; import {msg}  from 'iflux';");
    widgetArray.forEach(widgetNs=>{
        let _widgetName= widetUtil.extraWidgetNameFromPath(widgetNs);
        let widgetNameSpace = widgetNs;

        pathList.push('var '+_widgetName+' = require("'+widgetNameSpace+'");');
        pathList.push('var '+_widgetName+'P = require("'+widgetNameSpace+'-p");');
        pathList.push(_widgetName+'P.prototype.defaultProps.widget="'+_widgetName+'";');
        pathList.push(_widgetName+'P.prototype.defaultProps.widgetNameSpace="'+widgetNameSpace+'";');

        if(templateConfig && templateConfig.barDefaultPropsMap && templateConfig.barDefaultPropsMap[widgetNameSpace]) {
            //包含组件的转换属性...
            if(typeof templateConfig.barDefaultPropsMap[widgetNameSpace] === 'function'){
                //把函数源代码赋值过去.
                pathList.push(_widgetName+'P.prototype.defaultProps='+templateConfig.barDefaultPropsMap[widgetNameSpace].toString());
            } else {
                pathList.push(_widgetName+'P.prototype.defaultProps=$.extend(true,{},'+_widgetName+'P.prototype.defaultProps,'+JSON.stringify(templateConfig.barDefaultPropsMap[widgetNameSpace])+');');
            }
        }
        //自动注入过程..
        pathList.push(` msg.emit('__XSite_widgetInject',{widgetNameSpace:'${widgetNameSpace}',widget:${_widgetName},widgetP:${_widgetName+"P"}})`);

        //pathList.push('__XSite_widgectInject("'+widgetNameSpace+'",'+_widgetName+')');
        //pathList.push('__XSite_widgecPtInject("'+widgetNameSpace+'",'+_widgetName+')');
        //pathList.push('widgetRep["'+widgetNameSpace+'"]='+_widgetName+';');
        //pathList.push('widgetProxyRep["'+widgetNameSpace+'"]='+_widgetName+'P;');
        pathList.push('');//加一个空行间隔
    });
    //通知下内容已经加载过了.可以进行接下来的流程了.
    pathList.push('msg.emit("__XSite_Template_register",'+JSON.stringify(templateConfig)+');');
    pathList.push('msg.emit("__XSite_Template_Loaded_'+templateConfig.templateName+'","'+templateConfig.templateName+'");');
    //pathList.push('module.exports={ widgetRep,widgetProxyRep};');
    return pathList.join('\r');
}



/**
 * 根据配置文件生成包装的JS文件,主要用于异步加载的实现
 * 应当包含所有依赖组件条与组件块.
 * @param templateConfig or templa
 * @param options  {widgetTopDir:"",}
 * @deprecated 目前使用JS的方式来做
 */
templateUtil.generateTplWrapJs =function * (templateConfigOrPath,options){
    let templateConfig =templateConfigOrPath;
    if(typeof templateConfigOrPath ==='string'){
        templateConfig  = yield templateUtil.getTemplateConfig(templateConfigPath);
    }
    let dependentWidget = analyseTemplateDependentBar(templateConfig,options['widgetTopDir']);
    let result  = transferBar2Content(dependentWidget,templateConfig);
    return result;
}